import {
    createNavigationReducer,
} from 'react-navigation-redux-helpers';
import {
    NavigationActions,
} from 'react-navigation';
import * as Redux from 'redux';
import { BackHandler } from 'react-native';
import { store } from '../../store';
import {
    HardwareBackAction,
    Action,
    HardwareBackType,
} from '../../action';
import {
    AppStack,
} from '../../../constants/route';
import { StoreState } from '../../reducer';
import * as utils from '../../../utils';

BackHandler.addEventListener('hardwareBackPress', () => {
    store.dispatch(hardwareBackAction());
    return true;
});

export interface ConnectedUINavDispatch {
    _u_nav_navTo(routeName: string, params?: any, force?: boolean): void;
    _u_nav_navBack(force?: boolean): void;
}

const PREV_CHECK_TIME: any = {};
const CHECK_INTERVAL = 650;
function checkInterval(type: number, force?: boolean): boolean {
    const now = Date.now();
    const prev = PREV_CHECK_TIME[type] ? PREV_CHECK_TIME[type] : 0;
    if (force || (now >= prev)) {
        PREV_CHECK_TIME[type] = now + CHECK_INTERVAL;
        return true;
    }
    return false;
}

export const connect = (dispatch: Redux.Dispatch<any>, connected: any, mapKeys: any): ConnectedUINavDispatch => ({
    ...connected,
    _u_nav_navTo: (routeName: string, params?: any, force?: boolean) => checkInterval(0, force) && dispatch(navToAction(routeName, params)),
    _u_nav_navBack: (force?: boolean) => checkInterval(1, force) && dispatch(navBackAction()),
})

const navToAction = (routeName: string, params?: any): any => {
    return (dispatch: Redux.Dispatch<any>, getState: () => any) => {
        dispatch(NavigationActions.navigate({ routeName, params }));
    }
}

let appExit: boolean = false;
let appExitTimeHandler: number = 0;
const hardwareBackAction = (): any => {
    return (dispatch: Redux.Dispatch<any>, getState: () => any) => {
        const action: HardwareBackAction = {
            type: HardwareBackType,
            back: {},
        };
        const { routes } = appStackSelector(getState());
        if (utils.getLength(routes) <= 1) {
            action.back.appExit = true;
        }
        dispatch(action);
        if (action.back.appExit) {
            if (appExit) {
                BackHandler.exitApp();
            }
            else {
                appExit = true;
                appExitTimeHandler && clearTimeout(appExitTimeHandler);
                appExitTimeHandler = setTimeout(() => {
                    appExit = false;
                }, 3000);
            }
        }
        else if (!action.back.ignore) {
            dispatch(navBackAction());
        }
    }
}

const navBackAction = () => NavigationActions.back();

const _navReducer = createNavigationReducer(AppStack);
export function navReducer(state: any, action: any): any {
    return _navReducer(state, action);
}

export const appStackSelector = (state: StoreState) => state.ui.nav;